﻿using CinemaMaestro.BusinessLayer.Contracts;
using CinemaMaestro.DataLayer.Contracts;
using CinemaMaestro.DataLayer.Contracts.Entities;
using CinemaMaestro.WebApplication.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.Entity;

namespace CinemaMaestro.WebApplication.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var businessUoW = CinemaMaestro.Common.IocContainer.Resolver.Get<IBusinessObjectFactory>();
            var list = businessUoW.Movies.Read().AsNoTracking().Where(movie => movie.ReleaseDate >= DateTime.Now) .ToList();

            List<MovieViewModels> models = new List<MovieViewModels>();

            foreach (var model in list)
            {
                MovieViewModels movie = model;
                var base64 = model.Image != null ? Convert.ToBase64String(model.Image) : string.Empty;
                movie.Image = String.Format("data:image/jpg;base64,{0}", base64);
                models.Add(movie);
            }

            return View(models);
        }


        public ActionResult About(int id)
        {
            var businessUoW = CinemaMaestro.Common.IocContainer.Resolver.Get<IBusinessObjectFactory>();
            var movieModel = businessUoW.Movies.Read().AsNoTracking().Where(movie => movie.Id == id).FirstOrDefault();
            MovieViewModels movieViewModel = movieModel;
            if (movieModel != null)
            {
                var base64 = movieModel.Image != null ? Convert.ToBase64String(movieModel.Image) : string.Empty;
                movieViewModel.Image = String.Format("data:image/jpg;base64,{0}", base64);
            }
            
            return View(movieViewModel);
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }

        public JsonResult GetCinemas()
        {
            var businessUoW = CinemaMaestro.Common.IocContainer.Resolver.Get<IBusinessObjectFactory>();

            var list = businessUoW.Cinemas.Read().ToList();

            List<CinemaViewModels> models = new List<CinemaViewModels>();

            foreach (var model in list)
            {
                CinemaViewModels cinema = model;
                models.Add(cinema);
            }
            return new JsonResult { Data = models, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        public JsonResult GetMovies()
        {
            var businessUoW = CinemaMaestro.Common.IocContainer.Resolver.Get<IBusinessObjectFactory>();

            var list = businessUoW.Movies.Read().ToList();

            List<MovieViewModels> models = new List<MovieViewModels>();

            foreach (var model in list)
            {
                MovieViewModels movie = model;
                var base64 = model.Image != null ? Convert.ToBase64String(model.Image) : string.Empty;
                movie.Image = String.Format("data:image/jpg;base64,{0}", base64);
                models.Add(movie);
            }
            return new JsonResult { Data = models, JsonRequestBehavior = JsonRequestBehavior.AllowGet, MaxJsonLength = Int32.MaxValue };
        }

        public JsonResult GetData(int cinemaId, int movieId)
        {
            var businessUoW = CinemaMaestro.Common.IocContainer.Resolver.Get<IBusinessObjectFactory>();

            var list = businessUoW.Screenings.Read().Where(screening => screening.Room.Cinema.Id == cinemaId && screening.Movie.Id == movieId && screening.StartDate >= DateTime.Now).Distinct().Select(screening => new { StartDate = screening.StartDate, ScreeningId = screening.Id });

            return new JsonResult { Data = list, JsonRequestBehavior = JsonRequestBehavior.AllowGet};
        }

        public JsonResult GetMovie(int movieId)
        {
            var businessUoW = CinemaMaestro.Common.IocContainer.Resolver.Get<IBusinessObjectFactory>();

            var list = businessUoW.Movies.Read().Where(movie => movie.Id == movieId).Select(movie => new { movieName = movie.Title });

            return new JsonResult { Data = list, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        public JsonResult GetCinema(int movieId)
        {
            var businessUoW = CinemaMaestro.Common.IocContainer.Resolver.Get<IBusinessObjectFactory>();
            var list = businessUoW.Screenings.Read().ToList().Where(screening => screening.Movie.Id == movieId && screening.StartDate >= DateTime.Now).Select(x => new { cinemaId = x.Room.Cinema.Id, cinemaName = x.Room.Cinema.Name });

            return new JsonResult { Data = list.Distinct(), JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        public JsonResult GetTicketPrice(int cinemaId, int movieId, DateTime startDate, int languageId)
        {
            var businessUoW = CinemaMaestro.Common.IocContainer.Resolver.Get<IBusinessObjectFactory>();
            var list = businessUoW.Screenings.Read().Where(screening => screening.Room.Cinema.Id == cinemaId && screening.Movie.Id == movieId && screening.StartDate >= DateTime.Now && screening.StartDate == startDate && screening.Language.Id==languageId).Distinct().Select(screening => new { Price = screening.Price, DiscountedPrice = screening.DiscountedPrice});
            return new JsonResult { Data = list, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        public JsonResult GetLanguage(int screeningId)
        {
            var businessUoW = CinemaMaestro.Common.IocContainer.Resolver.Get<IBusinessObjectFactory>();

            var screening = businessUoW.Screenings.Read().FirstOrDefault(x => x.Id == screeningId);
            var capacity = screening.Room.Capacity;

            var reservedSeatCount = businessUoW.Reservations.Read()
                .Where(x => x.Screening.Id == screeningId)
                .Sum(x => x.TicketNr + x.DiscountTicketNr);

            var soldSeatCount = businessUoW.Sales.Read()
                .Where(x => x.Screening.Id == screeningId)
                .Sum(x => x.TicketNr + x.DiscountTicketNr);

            var availableTicket = capacity - soldSeatCount - reservedSeatCount;

            var list = businessUoW.Screenings.Read().Where(x => x.Id == screeningId).Select(x => new { LanguageId = x.Language.Id, LanguageName = x.Language.Name, Ticket = x.Price, DiscountedPrice = x.DiscountedPrice, AvailableTicket = availableTicket });
            return new JsonResult { Data = list, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        public JsonResult CreateReservation(int screeningId, int ticketNr, int discountedTicketNr, string name, string email, string telephone, string reservatedSeats)
        {
            var businessUoW = CinemaMaestro.Common.IocContainer.Resolver.Get<IBusinessObjectFactory>();

            var screening = businessUoW.Screenings.Read().AsNoTracking().First(x => x.Id == screeningId);

            var reservation = new ReservationViewModels();
            reservation.Screening = screening;
            reservation.TicketNr = ticketNr;
            reservation.DiscountTicketNr = discountedTicketNr;
            reservation.Name = name;
            reservation.Email = email;
            reservation.TelephoneNr = telephone;
            reservation.Seats = reservatedSeats.Substring(0,reservatedSeats.Length-1);

            var result = businessUoW.Reservations.Create(reservation);

            return new JsonResult {Data = result, JsonRequestBehavior=JsonRequestBehavior.AllowGet };
        }

        public JsonResult GetRoomSeats(int screeningId)
        {
            var businessUoW = CinemaMaestro.Common.IocContainer.Resolver.Get<IBusinessObjectFactory>();

            var screening = businessUoW.Screenings.Read().AsNoTracking().First(x => x.Id == screeningId);

            return new JsonResult { Data = screening.Room.Seats, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        public JsonResult GetReservatedSeats(int screeningId)
        {
            var businessUoW = CinemaMaestro.Common.IocContainer.Resolver.Get<IBusinessObjectFactory>();
             var reservedSeats = businessUoW.Reservations.Read()
                .Where(x => x.Screening.Id == screeningId)
                .Select(x => x.ReservatedSeats);

            var soldSeats = businessUoW.Sales.Read()
                .Where(x => x.Screening.Id == screeningId)
                .Select(x => x.Seats);

            var seats = string.Empty;
            if (reservedSeats.Count() > 0)
            {
                foreach(var item in reservedSeats)
                {
                    seats = seats + item + ",";
                }
            }

            if (soldSeats.Count() > 0)
            {
                foreach (var item in soldSeats)
                {
                    seats = seats + item + ",";
                }
            }

            if(seats.Length > 0)
                seats = seats.Substring(0,seats.Length - 1);

            return new JsonResult { Data = seats, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }
    }
}